using System.Collections;
using System.IO;

using System.Net.DnsToolkit.Packet;
using System.Net.DnsToolkit.Util;
using System.Net.DnsToolkit.Serializer.Stream.Extension;
using System.Net.DnsToolkit.Packet.Busy;

namespace System.Net.DnsToolkit.Serializer.Stream.Reader {

    public class HeaderReader : IHeaderReader<System.IO.Stream> {

        public IHeader Read(System.IO.Stream source) {
            IHeader header;
            Read(false, source, out header);
            return header;
        }

        public bool Read(bool tryRead, System.IO.Stream source, out IHeader header) {

            var h = new Header();

            h.Id = source.Read16();
            byte bqoatr = source.Read8();

            var ba = new BitArray(new[] { bqoatr });

            h.QueryType = Enum<QREnum>.ToObject(ba[7] ? 1 : 0);
            h.OpCode = Enum<OpCodeEnum>.ToObject((bqoatr & CompressionConstant.OpCodeMask) >> 3);

            h.AuthoritativeAnswer = ba[2];
            h.Truncation = ba[1];
            h.RecursionDesired = ba[0];

            byte brranr = source.Read8();
            var bb = new BitArray(new[] { brranr });

            h.RecursionAvailable = bb[7];
            h.Reserved = bb[6];
            h.AnswerAuthenticated = bb[5];
            h.NotAuthenticatedAcceptable = bb[4];

            h.ResponseCode = Enum<RCodeEnum>.ToObject(brranr & CompressionConstant.ResponseCodeMask);

            h.QuestionCount = source.Read16();
            h.AnswerCount = source.Read16();
            h.ResourceCount = source.Read16();
            h.AuthorityCount = source.Read16();
            
            header = h;

            return true;

        }

        public bool TryRead(System.IO.Stream source, out IHeader header) {
            return Read(true, source, out header);
        }
    }
}